import { Db, Collection, FindOptions, Filter, UpdateFilter, UpdateOptions, WithoutId } from "mongodb"
import { Movie, MovieSummary, MovieRating } from './types.ts'

export default class Movies {
  private movies: Collection<Movie>
  constructor(database: Db) {
    this.movies = database.collection<Movie>("movies")
  }

  async findOne(filter: any, options: FindOptions) {
    console.log('findOne')
    const movie = await this.movies.findOne<MovieSummary>(
      filter,
      options
    )
    console.log(movie)
  }

  async find(filter: any, options: FindOptions) {
    const movie = this.movies.find<Movie>(filter, options)
    console.log(movie)
    return movie
  }

  async updateOne(filter: Filter<Movie>, update: UpdateFilter<Movie>, options: UpdateOptions) {
    const result = await this.movies.updateOne(filter, update, options)
    console.log(
      `${result.matchedCount} document(s) matched the filter, updated ${result.modifiedCount} document(s)`
    )
  }

  async updateMany(filter: Filter<MovieRating>, update: UpdateFilter<MovieRating>) {
    const result = await this.movies.updateMany(filter, update)
    console.log(`Updated ${result.modifiedCount} documents`)
  }

  async replaceOne(filter: Filter<Movie>, replacement: any) {
    const result = await this.movies.replaceOne(filter, replacement)
    console.log(`Modified ${result.modifiedCount} document(s)`)
  }

  async deleteOne(filter: Filter<Movie>) {
    const result = await this.movies.deleteOne(filter)
    if (result.deletedCount === 1) {
      console.log('Successfully deleted one document.')
    } else {
      console.log('No documents matched the query. Deleted 0 documents.')
    }
  }

  async deleteMany(filter: Filter<Movie>) {
    const result = await this.movies.deleteMany(filter)
    console.log(`Deleted ${result.deletedCount} documents`)
  }

  /**
   * 查询集合中的文档数量，如果未指定入参，则查询集合中所有文档数量。若指定，则会根据指定的条件查找相关度的文档数量。
   * 如果空查询（查询集合总文档数量，可以使用collection.countDocuments({}, { hint: "_id_" })，这种效率更高）
   * @param filter 
   */
  countDocuments(filter: Filter<Movie>) {
    if (!filter) {
      this.movies.countDocuments({}, { hint: '_id' }).then(count => console.log(`document ${count}`))
    } else {
      this.movies.countDocuments(filter).then(count => console.log(`document ${count}`))
    }
  }

  /**
   * 根据集合元数据返回集合中文档的 估计 数量
   */
  estimatedDocumentCount() {
    this.movies.estimatedDocumentCount().then(count => console.log(`Estimated number of documents in the movies collection: ${count}`))
  }

  /**
   * distinct 命令返回集合中给定键的不同值列表。
   * @param key - 要查找不同值的文档的字段
   * @param filter（ 筛选条件） – 用于筛选我们应用 distinct 筛选条件的文档集的筛选条件。 
   * @param options  — 命令的可选设置
   */
  async distinct(key: any, filter: any, options?: FindOptions) {
    const result = await this.movies.distinct(key, filter, options || {})
    console.log(result)
  }

}